package com.gitee.qdbp.general.common.biz.sequence.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.api.sequence.model.StrongSequenceRule;
import com.gitee.qdbp.general.common.api.sequence.service.ILocalSequenceGenerator;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 本地序列号生成器(时间+序号)<br>
 * 12位时间(年月日时分秒)+主机编号+4位序号<br>
 * 对于这个实现来说, 如果集群部署, 那么主机编号是必须的
 *
 * @author zhaohuihua
 * @version 170722
 */
// @Service
public class TimeIndexSequenceGenerator implements ILocalSequenceGenerator {

    /** 本机的主机编号 **/
    private String hostCode;

    /** 默认的序号位数 **/
    private int digitNumber = 4;

    /** 时间部分的格式 **/
    private String timeFormat = "yyMMddHHmmss";

    private Map<String, StrongSequenceRule> map = new ConcurrentHashMap<>();

    /**
     * 生成一个新的序号
     * 
     * @param type 类型
     * @param subtypes 子类型
     * @return 序号
     * @throws ServiceException
     */
    @Override
    public String generate(String type, String... subtypes) throws ServiceException {
        synchronized (type.intern()) { // intern()确保相同字符串返回的是同一对象
            StrongSequenceRule bean = map.get(type);
            if (bean == null) {
                bean = new StrongSequenceRule(timeFormat, digitNumber);
                map.put(type, bean);
                if (bean.getCurrValue() <= 0) {
                    SequenceTools.next(bean);
                }
            } else {
                if (VerifyTools.isBlank(bean.getTimeFormat())) {
                    bean.setTimeFormat(timeFormat);
                }
                if (VerifyTools.isBlank(bean.getDigitNumber()) || bean.getDigitNumber() <= 0) {
                    bean.setDigitNumber(digitNumber);
                }
                SequenceTools.next(bean);
            }

            return SequenceTools.toString(bean, hostCode, bean.getCurrValue());
        }
    }

    /** 本机的主机编号(可为空) **/
    public String getHostCode() {
        return hostCode;
    }

    /** 本机的主机编号(可为空) **/
    public void setHostCode(String hostCode) {
        this.hostCode = hostCode;
    }

    /** 默认的序号位数 **/
    public int getDigitNumber() {
        return digitNumber;
    }

    /** 默认的序号位数 **/
    public void setDigitNumber(int digitNumber) {
        this.digitNumber = digitNumber;
    }

    /** 默认的时间部分的格式 **/
    public String getTimeFormat() {
        return timeFormat;
    }

    /** 默认的时间部分的格式 **/
    public void setTimeFormat(String timeFormat) {
        this.timeFormat = timeFormat;
    }

}
